#deepseek编的
import os
import shutil
import threading
from collections import defaultdict
import tkinter as tk
from tkinter import ttk, filedialog, messagebox

# 自定义分类规则
CATEGORY_RULES = {
    '图片': ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff'],
    '文档': ['pdf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'txt', 'rtf'],
    '音频': ['mp3', 'wav', 'flac', 'aac', 'ogg', 'wma'],
    '视频': ['mp4', 'avi', 'mkv', 'mov', 'wmv', 'flv', 'webm'],
    '压缩包': ['zip', 'rar', '7z', 'tar', 'gz', 'bz2'],
    '程序': ['exe', 'msi', 'bat', 'sh', 'py', 'js', 'html', 'css'],
    '数据': ['csv', 'json', 'xml', 'sql', 'db', 'sqlite']
}

class FileOrganizerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("文件分类整理工具")
        self.root.geometry("650x700")
        
        # 初始化变量
        self.process_existing = tk.BooleanVar(value=False)
        self.include_subfolders = tk.BooleanVar(value=False)
        self.selected_categories = {category: tk.BooleanVar(value=True) 
                                   for category in CATEGORY_RULES.keys()}
        self.selected_categories['其他'] = tk.BooleanVar(value=True)
        self.stop_requested = False
        
        # 设置样式
        self.style = ttk.Style()
        self.style.configure('TFrame', padding=10)
        self.style.configure('TButton', padding=5)
        self.style.configure('TLabel', padding=5, font=('Arial', 10))
        
        self.create_widgets()
    
    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 标题
        title_label = ttk.Label(main_frame, text="文件分类整理工具", font=('Arial', 14, 'bold'))
        title_label.pack(pady=10)
        
        # 文件夹选择部分
        folder_frame = ttk.Frame(main_frame)
        folder_frame.pack(fill=tk.X, pady=10)
        
        ttk.Label(folder_frame, text="选择要整理的文件夹:").pack(anchor=tk.W)
        
        self.folder_path = tk.StringVar()
        folder_entry = ttk.Entry(folder_frame, textvariable=self.folder_path, width=50)
        folder_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))
        
        browse_btn = ttk.Button(folder_frame, text="浏览...", command=self.browse_folder)
        browse_btn.pack(side=tk.RIGHT)
        
        # 选项部分
        options_frame = ttk.LabelFrame(main_frame, text="整理选项", padding=10)
        options_frame.pack(fill=tk.X, pady=10)
        
        # 是否包含子文件夹
        ttk.Checkbutton(
            options_frame, 
            text="包含子文件夹(整理所有一级子文件夹)",
            variable=self.include_subfolders
        ).pack(anchor=tk.W, pady=5)
        
        # 是否整理已有文件夹
        process_existing_check = ttk.Checkbutton(
            options_frame, 
            text="整理已有分类文件夹中的文件",
            variable=self.process_existing,
            command=self.toggle_category_selection
        )
        process_existing_check.pack(anchor=tk.W)
        
        # 分类选择部分
        self.category_frame = ttk.LabelFrame(main_frame, text="选择要整理的文件分类", padding=10)
        self.category_frame.pack(fill=tk.BOTH, expand=True, pady=10)
        
        # 分类选择按钮组
        btn_group_frame = ttk.Frame(self.category_frame)
        btn_group_frame.pack(fill=tk.X, pady=5)
        
        ttk.Button(btn_group_frame, text="全选", command=lambda: self.select_all_categories(True)).pack(side=tk.LEFT, padx=2)
        ttk.Button(btn_group_frame, text="全不选", command=lambda: self.select_all_categories(False)).pack(side=tk.LEFT, padx=2)
        ttk.Button(btn_group_frame, text="反选", command=self.toggle_categories).pack(side=tk.LEFT, padx=2)
        
        # 分类复选框
        self.category_checkboxes = {}
        categories_frame = ttk.Frame(self.category_frame)
        categories_frame.pack(fill=tk.BOTH, expand=True)
        
        for i, category in enumerate(sorted(CATEGORY_RULES.keys())):
            cb = ttk.Checkbutton(
                categories_frame,
                text=category,
                variable=self.selected_categories[category],
                onvalue=True,
                offvalue=False
            )
            cb.grid(row=i//3, column=i%3, sticky=tk.W, padx=5, pady=2)
            self.category_checkboxes[category] = cb
        
        # 其他分类复选框
        cb = ttk.Checkbutton(
            categories_frame,
            text="其他",
            variable=self.selected_categories['其他'],
            onvalue=True,
            offvalue=False
        )
        cb.grid(row=(len(CATEGORY_RULES)//3)+1, column=0, sticky=tk.W, padx=5, pady=2)
        self.category_checkboxes['其他'] = cb
        
        # 进度条
        self.progress_frame = ttk.Frame(main_frame)
        self.progress_frame.pack(fill=tk.X, pady=10)
        
        self.progress_label = ttk.Label(self.progress_frame, text="进度: 0% (0/0)")
        self.progress_label.pack(anchor=tk.W)
        
        self.progress_bar = ttk.Progressbar(self.progress_frame, orient=tk.HORIZONTAL, length=100, mode='determinate')
        self.progress_bar.pack(fill=tk.X)
        
        # 操作按钮
        btn_frame = ttk.Frame(main_frame)
        btn_frame.pack(fill=tk.X, pady=10)
        
        self.organize_btn = ttk.Button(btn_frame, text="开始整理", command=self.start_organization)
        self.organize_btn.pack(side=tk.LEFT, padx=5)
        
        self.stop_btn = ttk.Button(btn_frame, text="停止", command=self.stop_organization, state=tk.DISABLED)
        self.stop_btn.pack(side=tk.LEFT, padx=5)
        
        exit_btn = ttk.Button(btn_frame, text="退出", command=self.root.quit)
        exit_btn.pack(side=tk.RIGHT, padx=5)
        
        # 状态栏
        self.status_var = tk.StringVar()
        self.status_var.set("准备就绪")
        status_bar = ttk.Label(main_frame, textvariable=self.status_var, relief=tk.SUNKEN)
        status_bar.pack(fill=tk.X, pady=(10, 0))
        
        # 初始禁用分类选择
        self.toggle_category_selection()
    
    def browse_folder(self):
        """浏览选择文件夹"""
        folder_selected = filedialog.askdirectory()
        if folder_selected:
            self.folder_path.set(folder_selected)
            self.status_var.set(f"已选择文件夹: {folder_selected}")
    
    def toggle_category_selection(self):
        """切换分类选择区域的状态"""
        state = '!disabled' if self.process_existing.get() else 'disabled'
        for cb in self.category_checkboxes.values():
            cb.state([state])
    
    def select_all_categories(self, select):
        """全选或全不选分类"""
        for var in self.selected_categories.values():
            var.set(select)
    
    def toggle_categories(self):
        """反选分类"""
        for var in self.selected_categories.values():
            var.set(not var.get())
    
    def start_organization(self):
        """开始整理文件"""
        source_folder = self.folder_path.get()
        
        if not source_folder:
            messagebox.showerror("错误", "请先选择要整理的文件夹！")
            return
        
        if not os.path.exists(source_folder):
            messagebox.showerror("错误", f"文件夹 '{source_folder}' 不存在！")
            return
        
        # 获取要处理的分类
        selected_cats = [cat for cat, var in self.selected_categories.items() if var.get()]
        if not selected_cats and self.process_existing.get():
            messagebox.showerror("错误", "请至少选择一个分类！")
            return
        
        # 重置停止标志
        self.stop_requested = False
        
        # 更新按钮状态
        self.organize_btn.config(state=tk.DISABLED)
        self.stop_btn.config(state=tk.NORMAL)
        self.root.config(cursor="watch")
        
        # 在后台线程中执行整理操作
        threading.Thread(
            target=self.organize_files,
            args=(source_folder, selected_cats),
            daemon=True
        ).start()
    
    def stop_organization(self):
        """停止整理过程"""
        self.stop_requested = True
        self.status_var.set("正在停止...")
    
    def update_progress(self, processed, total, current_file, current_category):
        """更新进度显示"""
        if total > 0:
            progress = int((processed / total) * 100)
            self.progress_bar['value'] = progress
            self.progress_label.config(text=f"进度: {progress}% ({processed}/{total})")
            self.status_var.set(f"正在整理: {current_file} → {current_category}")
    
    def organize_files(self, source_folder, selected_cats):
        """整理文件"""
        try:
            # 统计文件分类
            file_stats = defaultdict(int)
            total_files = 0
            processed_files = 0
            
            # 收集所有要处理的文件夹
            folders_to_process = [source_folder]
            if self.include_subfolders.get():
                for item in os.listdir(source_folder):
                    item_path = os.path.join(source_folder, item)
                    if os.path.isdir(item_path):
                        folders_to_process.append(item_path)
            
            # 先扫描所有文件以计算总数
            all_files = []
            for folder in folders_to_process:
                for filename in os.listdir(folder):
                    file_path = os.path.join(folder, filename)
                    
                    if os.path.isdir(file_path):
                        continue
                    
                    all_files.append((folder, filename))
            
            total_files = len(all_files)
            
            if total_files == 0:
                self.root.after(0, lambda: messagebox.showinfo("信息", "没有找到可整理的文件！"))
                return
            
            # 处理每个文件
            for folder, filename in all_files:
                if self.stop_requested:
                    break
                
                file_path = os.path.join(folder, filename)
                
                _, ext = os.path.splitext(filename)
                ext = ext[1:].lower()
                
                # 查找文件所属类别
                category = "其他"
                for cat, exts in CATEGORY_RULES.items():
                    if ext in exts:
                        category = cat
                        break
                
                # 如果不需要处理已有分类文件夹中的文件，跳过已在分类文件夹中的文件
                if not self.process_existing.get():
                    file_dir = os.path.dirname(file_path)
                    if os.path.basename(file_dir) in CATEGORY_RULES.keys() or os.path.basename(file_dir) == "其他":
                        processed_files += 1
                        self.root.after(0, lambda: self.update_progress(
                            processed_files, total_files, filename, category
                        ))
                        continue
                
                # 检查是否选择了该分类
                if category not in selected_cats and self.process_existing.get():
                    processed_files += 1
                    self.root.after(0, lambda: self.update_progress(
                        processed_files, total_files, filename, category
                    ))
                    continue
                
                # 创建目标文件夹
                target_folder = os.path.join(folder, category)
                if not os.path.exists(target_folder):
                    os.makedirs(target_folder)
                
                # 移动文件
                try:
                    shutil.move(file_path, os.path.join(target_folder, filename))
                    file_stats[category] += 1
                    processed_files += 1
                    
                    # 更新进度
                    self.root.after(0, lambda: self.update_progress(
                        processed_files, total_files, filename, category
                    ))
                except Exception as e:
                    print(f"移动 {filename} 失败: {e}")
            
            # 整理完成后更新界面
            self.root.after(0, self.finish_organization, file_stats, processed_files, total_files)
            
        except Exception as e:
            self.root.after(0, lambda: messagebox.showerror("错误", f"整理过程中发生错误: {str(e)}"))
            self.root.after(0, lambda: setattr(self.status_var, "set", "整理出错"))
        finally:
            self.root.after(0, self.reset_ui)
    
    def finish_organization(self, file_stats, processed_files, total_files):
        """整理完成后显示结果"""
        if self.stop_requested:
            result_msg = f"整理已停止！共处理了 {processed_files} 个文件(共 {total_files} 个)"
        else:
            result_msg = f"整理完成！共处理了 {processed_files} 个文件(共 {total_files} 个)\n\n"
        
        if file_stats:
            result_msg += "\n".join([f"{category}: {count} 个文件" 
                                   for category, count in file_stats.items()])
        else:
            result_msg += "\n没有文件被移动（可能所有文件已在正确分类中）"
        
        messagebox.showinfo("整理完成" if not self.stop_requested else "整理已停止", result_msg)
        self.status_var.set(f"整理{'完成' if not self.stop_requested else '已停止'}！共处理了 {processed_files} 个文件")
        self.progress_label.config(text=f"整理{'完成' if not self.stop_requested else '已停止'}！")
    
    def reset_ui(self):
        """重置UI状态"""
        self.organize_btn.config(state=tk.NORMAL)
        self.stop_btn.config(state=tk.DISABLED)
        self.root.config(cursor="")

if __name__ == "__main__":
    root = tk.Tk()
    app = FileOrganizerApp(root)
    root.mainloop()